using System;
using PluginFrame;

namespace PcrDataAnalysis
{
    public class AutoBaseLineNormalization : ManualBaseLineNormalization, IBaseLineNormalization
    {
        protected int mAutoOptimizationCycle;

        protected IAnalysisAlgorithmConfiguration mAnalysisConfiguration;

        public AutoBaseLineNormalization(IApplication app)
            : base(app)
        {
            mAnalysisConfiguration = mConfigurationService.AnalysisConfiguration;
            mAutoOptimizationCycle = mAnalysisConfiguration.AutoOptimizationCycle;
        }

        protected void CheckBaseLine(int cycleCount)
        {
            if (mStopBaseLine <= mAnalysisConfiguration.AutoBaseLineMinStartValue)
            {
                mStopBaseLine = mAnalysisConfiguration.AutoBaseLineMinStartValue + 1;
            }
            mAnalysisConfiguration.AutoBaseLineDefaultInterval = 8;
            if (mStopBaseLine - mStartBaseLine >= mAnalysisConfiguration.AutoBaseLineDefaultInterval)
            {
                return;
            }
            mStartBaseLine = mStopBaseLine - mAnalysisConfiguration.AutoBaseLineDefaultInterval;
            if (mStartBaseLine < mAnalysisConfiguration.AutoBaseLineMinStartValue)
            {
                mStartBaseLine = mAnalysisConfiguration.AutoBaseLineMinStartValue;
                if (mStopBaseLine < mAnalysisConfiguration.AutoBaseLineDefaultInterval)
                {
                    mStopBaseLine = mAnalysisConfiguration.AutoBaseLineDefaultInterval;
                }
                if (mStopBaseLine > cycleCount)
                {
                    mStopBaseLine = cycleCount;
                }
            }
        }

        protected void InitializeAutoOptimizationBaseLine(double[] channelData, int amplificationCount)
        {
            double num = Math.Pow(2.0, 0.04);
            bool flag = false;
            try
            {
                for (int i = mStartBaseLine - 1; i < amplificationCount - 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        double num2 = channelData[i + j];
                        double num3 = channelData[i + j + 1];
                        double num4 = num3 / num2;
                        if (num4 > num)
                        {
                            flag = true;
                            continue;
                        }
                        flag = false;
                        break;
                    }
                    if (flag)
                    {
                        if (mStopBaseLine <= i - 5 + 1)
                        {
                            mStopBaseLine = i - 5 + 1;
                        }
                        else
                        {
                            mStopBaseLine = i - 2;
                        }
                        break;
                    }
                }
            }
            catch (Exception)
            {
                flag = false;
            }
            if (!flag)
            {
                mAutoOptimizationCycle = mAnalysisConfiguration.AutoOptimizationCycle;
                CheckBaseLine(amplificationCount);
                return;
            }
            mAutoOptimizationCycle = 1;
            if (mStopBaseLine >= 12)
            {
                CheckBaseLine(amplificationCount);
                return;
            }
            if (mStopBaseLine >= 9)
            {
                mStartBaseLine = 4;
                return;
            }
            if (mStopBaseLine >= 6)
            {
                mStartBaseLine = 3;
                return;
            }
            if (mStopBaseLine >= 3)
            {
                mStartBaseLine = 2;
                return;
            }
            mStartBaseLine = 1;
            mStopBaseLine = 1;
        }

        protected void PreAnalysisNormalization(IPcrCell pcrCell, int channelIndex, int startBaseLine, int stopBaseLine, double[] channelData)
        {
            try
            {
                if (pcrCell.CellPosition == "A1")
                {
                }
                int num = 0;
                try
                {
                    if (pcrCell.Project != null)
                    {
                        num = pcrCell.Project.PcrProgram.AmplificationDetectionCount;
                    }
                    else if (pcrCell.PcrExperiment != null && pcrCell.PcrExperiment.Projects != null)
                    {
                        num = pcrCell.PcrExperiment.Projects[0].PcrProgram.AmplificationDetectionCount;
                    }
                    if (num > channelData.Length)
                    {
                        num = channelData.Length;
                    }
                }
                catch (Exception)
                {
                    num = channelData.Length;
                }
                if (num > 0)
                {
                    InitializeAutoOptimizationBaseLine(channelData, num);
                }
                else
                {
                    mAutoOptimizationCycle = 1;
                }
                pcrCell.SetAutoBaseLineStartValue(channelIndex, mStartBaseLine);
                pcrCell.SetAutoBaseLineStopValue(channelIndex, mStopBaseLine);
                pcrCell.SetAutoBaseLineRotationCount(channelIndex, mAutoOptimizationCycle);
            }
            catch (Exception)
            {
            }
        }

        protected void AnalysisNormalization(IPcrCell pcrCell, int channelIndex, double[] channelData)
        {
            if (pcrCell.CellPosition == "D8")
            {
            }
            double[] channelLightData = pcrCell.GetChannelRawData(channelIndex, true);
            int num = 0;
            try
            {
                if (pcrCell.Project != null)
                {
                    num = pcrCell.Project.PcrProgram.AmplificationDetectionCount;
                }
                else if (pcrCell.PcrExperiment != null && pcrCell.PcrExperiment.Projects != null)
                {
                    num = pcrCell.PcrExperiment.Projects[0].PcrProgram.AmplificationDetectionCount;
                }
                if (num > channelData.Length)
                {
                    num = channelData.Length;
                }
            }
            catch (Exception)
            {
                num = channelData.Length;
            }
            double num2 = pcrCell.GetAutoBaseLineRotationCount(channelIndex);
            if (num2 > 1.0)
            {
                int autoOptimizationDefaultStartValue = mAnalysisConfiguration.AutoOptimizationDefaultStartValue;
                int num3 = 0;
                int num4 = pcrCell.GetAutoBaseLineStartValue(channelIndex);
                int num5 = pcrCell.GetAutoBaseLineStopValue(channelIndex);
                for (int i = 1; i <= mAutoOptimizationCycle; i++)
                {
                    num4 = pcrCell.GetAutoBaseLineStartValue(channelIndex);
                    num5 = pcrCell.GetAutoBaseLineStopValue(channelIndex);
                    double num6 = CalculateBaseLineAverage(channelLightData, num4, num5);
                    double num7 = Math.Pow(2.0, mAnalysisConfiguration.AutoOptimizationThreshold) * num6;
                    num3 = 0;
                    for (int j = autoOptimizationDefaultStartValue; j <= num; j++)
                    {
                        if (!double.IsNaN(channelLightData[j - 1]) && channelLightData[j - 1] >= num7)
                        {
                            num3 = j;
                            break;
                        }
                    }
                    if (num3 == 0)
                    {
                        num3 = ((num > channelLightData.Length) ? num : channelLightData.Length);
                    }
                    num5 = num3 - 5;
                    if (num5 <= mAnalysisConfiguration.AutoBaseLineMinStartValue)
                    {
                        num5 = pcrCell.GetAutoBaseLineStopValue(channelIndex);
                        num4 = pcrCell.GetAutoBaseLineStartValue(channelIndex);
                    }
                    else
                    {
                        mAnalysisConfiguration.AutoBaseLineDefaultInterval = 8;
                        if (num5 - num4 < mAnalysisConfiguration.AutoBaseLineDefaultInterval)
                        {
                            num4 = num5 - mAnalysisConfiguration.AutoBaseLineDefaultInterval;
                            if (num4 < mAnalysisConfiguration.AutoBaseLineMinStartValue)
                            {
                                num4 = mAnalysisConfiguration.AutoBaseLineMinStartValue;
                                if (num5 < mAnalysisConfiguration.AutoBaseLineDefaultInterval)
                                {
                                    num5 = mAnalysisConfiguration.AutoBaseLineDefaultInterval;
                                }
                                if (num5 > num)
                                {
                                    num5 = num;
                                }
                            }
                        }
                    }
                    RotateTranlateData(pcrCell, ref channelLightData, channelIndex, num4, num5);
                    if (num3 == channelLightData.Length)
                    {
                        break;
                    }
                }
                mStartBaseLine = num4;
                mStopBaseLine = num5;
            }
            else
            {
                mStartBaseLine = pcrCell.GetAutoBaseLineStartValue(channelIndex);
                mStopBaseLine = pcrCell.GetAutoBaseLineStopValue(channelIndex);
                RotateTranlateData(pcrCell, ref channelLightData, channelIndex, mStartBaseLine, mStopBaseLine);
            }
            mRotateCurve = false;
            base.ChannelNormalization(pcrCell, channelIndex, true, mStartBaseLine, mStopBaseLine, channelLightData);
        }

        protected override void ChannelNormalization(IPcrCell pcrCell, int channelIndex, bool isAnalyzing, int startBaseLine, int stopBaseLine, double[] channelData)
        {
            if (isAnalyzing)
            {
                pcrCell.CellPosition.Equals("A5");
                AnalysisNormalization(pcrCell, channelIndex, channelData);
            }
            else
            {
                PreAnalysisNormalization(pcrCell, channelIndex, startBaseLine, stopBaseLine, channelData);
            }
        }

        public new AnalysisError Execute(IPcrCell pcrCell, IAbsoluteAnalysisParameterConfiguration analysisOption, int channelIndex, bool isAnalyzing)
        {
            return base.Execute(pcrCell, analysisOption, channelIndex, isAnalyzing);
        }
    }
}
